View Javadoc

1   // B2QUnsafeHandler.java, created Mon Dec 23 23:00:34 2002 by mcmartin
2   // Copyright (C) 2001-3 mcmartin
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.Compiler.Quad;
5   
6   import joeq.Class.jq_Method;
7   import joeq.Class.jq_Primitive;
8   import joeq.Compiler.Quad.Operand.RegisterOperand;
9   import joeq.Compiler.Quad.Operator.Special;
10  import joeq.Compiler.Quad.Operator.Unary;
11  import joeq.Memory.Address;
12  import joeq.Memory.CodeAddress;
13  import joeq.Memory.StackAddress;
14  import joeq.Runtime.Unsafe;
15  import joeq.Scheduler.jq_Thread;
16  import jwutil.util.Assert;
17  
18  /*
19   * @author  Michael Martin <mcmartin@stanford.edu>
20   * @version $Id: B2QUnsafeHandler.java 2074 2004-12-10 19:02:26Z joewhaley $
21   */
22  class B2QUnsafeHandler implements BytecodeToQuad.UnsafeHelper {
23      public boolean isUnsafe(jq_Method m) {
24          return m.getDeclaringClass() == Unsafe._class;
25      }
26      public boolean endsBB(jq_Method m) {
27          return m == Unsafe._longJump;
28      }
29      public boolean handleMethod(BytecodeToQuad b2q, ControlFlowGraph quad_cfg, BytecodeToQuad.AbstractState current_state, jq_Method m, Operator.Invoke oper) {
30          Quad q;
31          if (m == Unsafe._floatToIntBits) {
32              Operand op = current_state.pop_F();
33              RegisterOperand res = b2q.getStackRegister(jq_Primitive.INT);
34              q = Unary.create(quad_cfg.getNewQuadID(), Unary.FLOAT_2INTBITS.INSTANCE, res, op);
35              current_state.push_I(res.copy());
36          } else if (m == Unsafe._intBitsToFloat) {
37              Operand op = current_state.pop_I();
38              RegisterOperand res = b2q.getStackRegister(jq_Primitive.FLOAT);
39              q = Unary.create(quad_cfg.getNewQuadID(), Unary.INTBITS_2FLOAT.INSTANCE, res, op);
40              current_state.push_F(res.copy());
41          } else if (m == Unsafe._doubleToLongBits) {
42              Operand op = current_state.pop_D();
43              RegisterOperand res = b2q.getStackRegister(jq_Primitive.LONG);
44              q = Unary.create(quad_cfg.getNewQuadID(), Unary.DOUBLE_2LONGBITS.INSTANCE, res, op);
45              current_state.push_L(res.copy());
46          } else if (m == Unsafe._longBitsToDouble) {
47              Operand op = current_state.pop_L();
48              RegisterOperand res = b2q.getStackRegister(jq_Primitive.DOUBLE);
49              q = Unary.create(quad_cfg.getNewQuadID(), Unary.LONGBITS_2DOUBLE.INSTANCE, res, op);
50              current_state.push_D(res.copy());
51          } else if (m == Unsafe._getThreadBlock) {
52              RegisterOperand res = b2q.getStackRegister(jq_Thread._class);
53              q = Special.create(quad_cfg.getNewQuadID(), Special.GET_THREAD_BLOCK.INSTANCE, res);
54              current_state.push_A(res.copy());
55          } else if (m == Unsafe._setThreadBlock) {
56              Operand loc = current_state.pop_A();
57              q = Special.create(quad_cfg.getNewQuadID(), Special.SET_THREAD_BLOCK.INSTANCE, loc);
58          } else if (m == Unsafe._longJump) {
59              Operand eax = current_state.pop_I();
60              Operand sp = current_state.pop(StackAddress._class);
61              Operand fp = current_state.pop(StackAddress._class);
62              Operand ip = current_state.pop(CodeAddress._class);
63              q = Special.create(quad_cfg.getNewQuadID(), Special.LONG_JUMP.INSTANCE, ip, fp, sp, eax);
64          } else if (m == Unsafe._popFP32) {
65              RegisterOperand res = b2q.getStackRegister(jq_Primitive.FLOAT);
66              q = Special.create(quad_cfg.getNewQuadID(), Special.POP_FP32.INSTANCE, res);
67              current_state.push_F(res.copy());
68          } else if (m == Unsafe._popFP64) {
69              RegisterOperand res = b2q.getStackRegister(jq_Primitive.DOUBLE);
70              q = Special.create(quad_cfg.getNewQuadID(), Special.POP_FP64.INSTANCE, res);
71              current_state.push_D(res.copy());
72          } else if (m == Unsafe._pushFP32) {
73              Operand val = current_state.pop_F();
74              q = Special.create(quad_cfg.getNewQuadID(), Special.PUSH_FP32.INSTANCE, val);
75          } else if (m == Unsafe._pushFP64) {
76              Operand val = current_state.pop_D();
77              q = Special.create(quad_cfg.getNewQuadID(), Special.PUSH_FP64.INSTANCE, val);
78          } else if (m == Unsafe._EAX) {
79              RegisterOperand res = b2q.getStackRegister(jq_Primitive.INT);
80              q = Special.create(quad_cfg.getNewQuadID(), Special.GET_EAX.INSTANCE, res);
81              current_state.push_I(res.copy());
82          } else if (m == Unsafe._pushArg) {
83              Operand val = current_state.pop_I();
84              q = Special.create(quad_cfg.getNewQuadID(), Special.PUSHARG_I.INSTANCE, val);
85          } else if (m == Unsafe._pushArgA) {
86              Operand val = current_state.pop_P();
87              q = Special.create(quad_cfg.getNewQuadID(), Special.PUSHARG_P.INSTANCE, val);
88          } else if (m == Unsafe._invoke) {
89              Operand loc = current_state.pop_P();
90              RegisterOperand res = b2q.getStackRegister(jq_Primitive.LONG);
91              q = Special.create(quad_cfg.getNewQuadID(), Special.INVOKE_L.INSTANCE, res, loc);
92              current_state.push_L(res.copy());
93          } else if (m == Unsafe._invokeA) {
94              Operand loc = current_state.pop_P();
95              RegisterOperand res = b2q.getStackRegister(Address._class);
96              q = Special.create(quad_cfg.getNewQuadID(), Special.INVOKE_P.INSTANCE, res, loc);
97              current_state.push_P(res.copy());
98          } else if (m == Unsafe._isEQ) {
99              RegisterOperand res = b2q.getStackRegister(jq_Primitive.BOOLEAN);
100             q = Special.create(quad_cfg.getNewQuadID(), Special.ISEQ.INSTANCE, res);
101             current_state.push_I(res.copy());
102         } else if (m == Unsafe._isGE) {
103             RegisterOperand res = b2q.getStackRegister(jq_Primitive.BOOLEAN);
104             q = Special.create(quad_cfg.getNewQuadID(), Special.ISGE.INSTANCE, res);
105             current_state.push_I(res.copy());
106         } else {
107             System.err.println(m.toString());
108             Assert.UNREACHABLE();
109             return false;
110         }
111         b2q.appendQuad(q);
112         return true;
113     }
114 }